package middleware

import (
	"context"
	"fmt"
	"strings"

	"gitee.com/lishixi/gops/vblog/apps/token"
	"github.com/gin-gonic/gin"
	"github.com/infraboard/mcube/v2/exception"
	"github.com/infraboard/mcube/v2/http/gin/response"
	"github.com/infraboard/mcube/v2/ioc/config/log"
)

// type HandlerFunc func(*Context)
// 补充认证逻辑
// 1. 获取 token , Cookie , Header, Authorization: 存放用户认证信息 Authorization: <token_type> <token_value>, Bearer: xxxxxx
// 2. 验证 token
// 3. 注入用户信息
func Auth(c *gin.Context) {
	// 获取 token
	accessToken := c.GetHeader("Authorization")
	tkList := strings.Split(accessToken, " ")

	accessToken = ""
	if len(tkList) == 2 {
		accessToken = tkList[1]
	}

	if accessToken == "" {
		tc, err := c.Cookie(token.COOKIE_NAME)
		if err != nil {
			log.L().Error().Msgf("get cookie error: %s", err)
		} else {
			accessToken = tc
		}
	}
	//验证 token
	tk, err := token.GetService().ValidateToken(c.Request.Context(), token.NewValidateTokenRequest(accessToken))
	if err != nil {
		response.Failed(c, exception.NewUnauthorized("令牌校验失败：%s", err))
		c.Abort()
		return
	}

	// 注入用户信息
	// 这里第二个参数建议使用内荐类型，所以用了一个空结构体 TokenCtxKey
	ctx := context.WithValue(c.Request.Context(), TokenCtxKey{}, tk)
	fmt.Println(tk)
	c.Request = c.Request.WithContext(ctx)
}

type TokenCtxKey struct{}

func GetTokenFromCtx(ctx context.Context) *token.Token {
	return ctx.Value(TokenCtxKey{}).(*token.Token)
}
